package zd.vrp.initsolution;

import zd.vrp.global.City;
import zd.vrp.global.GlobalInformation;
import zd.vrp.global.Route;
import zd.vrp.utils.TestUtils;

public class SolomonInsertion2 {

	// find next city and insert into a route
	public static void insertCityByNearestNeighbor() {

		// record current best
		City currentBestCity = null;
		double arrivalTimeT = 0;
		double currentBestValue = 100000;

		// find current route
		int currentRouteSize = GlobalInformation.routeList.size();
		Route currentRoute = null;
		if (currentRouteSize == 0) {
			currentRoute = new Route();
			GlobalInformation.routeList.add(currentRoute);
		} else {
			currentRoute = GlobalInformation.routeList
					.get(currentRouteSize - 1);
		}

		City previousCity = currentRoute.getCityList().get(
				currentRoute.getLastCityIndex() - 1);
		// iterate each unvisited citeis and calculate insertion cost

		for (int i = previousCity.getId() * GlobalInformation.cityNum; i < ((previousCity
				.getId() + 1) * GlobalInformation.cityNum); i++) {
			int nextCityIndex = GlobalInformation.ranks[i];
			if (nextCityIndex != 0 && nextCityIndex != previousCity.getId()) {
				System.out.println("------------------------");
				City nextCity = GlobalInformation.cityList.get(nextCityIndex);

				double distance = GlobalInformation.distance[previousCity
						.getId()
						* GlobalInformation.cityNum + nextCity.getId()];

				if (nextCity.getRoute() == null) {
					double arrivalTime = currentRoute.arrivalTime4InsertedCity(
							nextCity, currentRoute.getLastCityIndex());

					// arrival time shoule not be later than lastest allowed
					// arrival time
					if (arrivalTime <= nextCity.getLtime()) {
						double startTime = Math.max(arrivalTime, nextCity
								.getEtime());

						double Tij = startTime - previousCity.getFinishTime();

						double Vij = nextCity.getLtime() - arrivalTime;

						double Cij = GlobalInformation.theta1 * distance
								+ GlobalInformation.theta2 * Tij
								+ GlobalInformation.theta3 * Vij;

						// check whether this city is feasible and has less
						// insertion cost
						if ((Cij < currentBestValue)
								&& (currentRoute
										.checkDemandFeasibility(nextCity))) {
							currentBestValue = Cij;
							currentBestCity = nextCity;
							arrivalTimeT = arrivalTime;
						}
					}else{
						System.out.println("time window violation!!!");
						System.out.println("previous city id:"+previousCity.getId());
						System.out.println("next city id:"+nextCity.getId());						
						System.out.println("arrivalTime:"+arrivalTime);
						System.out.println("lastest time:"+nextCity.getLtime());
						
						System.out.println("remaining unvisited cities:"+GlobalInformation.unvisitedCity);
					}
				}

			}
			System.out.println("------------------------");
		}

		if (currentBestCity != null) {
			currentRoute.insertCityIntoRoute(currentBestCity, currentRoute
					.getLastCityIndex());

		} else {
			// create a new route
			currentRoute = new Route();
			GlobalInformation.routeList.add(currentRoute);
		}
	}

	// calculate time interval between

}
